﻿using AutoMapper;
using B.MES.Customer.Domain;
using B.MES.Customer.Domain.DTO;
using B.MES.Customer.Infrastructure.IRepository;
using CSRedis;
using MySqlX.XDevAPI;
using Newtonsoft.Json;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Drawing.Printing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using Yitter.IdGenerator;

namespace B.MES.Customer.Infrastructure.Repository
{
    /// <summary>
    /// 出库仓储实现层
    /// </summary>
    public class OutboundRepository : BaseRepository<OutWarehouse>, IOutboundRepository
    {
        /// <summary>
        /// 上下文sqlsugar
        /// </summary>
        private readonly ISqlSugarClient _db;
        /// <summary>
        ///  Mapper 映射
        /// </summary>
        private readonly IMapper _mapper;
        /// <summary>
        /// RedisClient 实例
        /// </summary>
        private readonly RedisClient _redis;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="db">上下文sqlsugar</param>
        public OutboundRepository(ISqlSugarClient db, IMapper mapper) : base(db)
        {
            _db = db;
            _mapper = mapper;
            _redis = new RedisClient("10.31.59.13");
        }
        /// <summary>
        /// 显示、分页、查询出库列表
        /// </summary>
        /// <param name="pageSize">每页显示条数</param>
        /// <param name="pageIndex">当前页码</param>
        /// <param name="outTopic">出库主题</param>
        /// <returns> 显示、分页、查询出库列表</returns>
        public PageApiResut<OutWareHouseDto> GetOutWare(int pageSize, int pageIndex, string? outTopic)
        {
            var query = _db.Queryable<OutTab, Material>((ot, m) => ot.OutId == m.MatId)
                           .WhereIF(!string.IsNullOrEmpty(outTopic), (ot, m) => ot.OutTopic.Contains(outTopic))
                           .OrderBy(ot => ot.OutId, OrderByType.Desc)
                           .Select((ot, m) => new OutWareHouseDto
                           {
                               OutId = ot.OutId,
                               OutType = ot.OutType,
                               OutNum = ot.OutNum,
                               OutTopic = ot.OutTopic,
                               OutDate = ot.OutDate,
                               OutWareHouse = ot.OutWareHouse,
                               Applicant = ot.Applicant,
                               OutName = ot.OutName,
                               Remark = ot.Remark,
                               OutCount = ot.OutCount,
                               MatPrice = m.MatPrice, 
                           });

            var totalCount = query.Count();

            var pageData = query.ToPageList(pageIndex, pageSize).ToList();

            var result = new PageApiResut<OutWareHouseDto>
            {
                TotalCount = totalCount,
                Data = pageData,
            };

            return result;
        }

        /// <summary>
        /// 查看出库详情
        /// </summary>
        /// <param name="outId">出库编号</param>
        /// <returns>出库详情</returns>
        public APIResult<OutWareHouseDto> GetOutDetail(int outId)
        {
            APIResult<OutWareHouseDto> aPIResult = new APIResult<OutWareHouseDto>();
            // 使用 SqlSugar 查询数据
            var outList = _db.Queryable<OutTab>().Where(t => t.OutId == outId).First();
            if (outList != null)
            {
                aPIResult.Data = new OutWareHouseDto
                {
                    OutId = outList.OutId,
                    OutDate = outList.OutDate,
                    OutCount = outList.OutCount,
                    OutName = outList.OutName,
                    OutNum = outList.OutNum,
                    OutTopic = outList.OutTopic,
                    OutType = outList.OutType,
                    OutWareHouse = outList.OutWareHouse,
                    Applicant = outList.Applicant,
                    Remark = outList.Remark,

                };
                return aPIResult;
            }
            else
            {
                return null;
            }
        }
        ///// <summary>
        ///// 添加出库信息
        ///// </summary>
        ///// <param name="outTab">出库表实体</param>
        ///// <returns>受影响行数</returns>
        //public int AddOutTab(OutTab outTab)
        //{
        //    //雪花ID
        //    //outTab.OutNum = YitIdHelper.NextId().ToString();
        //    return _db.Insertable(outTab).ExecuteCommand();
        //}
        /// <summary>
        /// 添加出库信息并更改生产单状态
        /// </summary>
        /// <param name="outTab">出库表</param>
        /// <param name="proCode"> 生产单编号</param>
        /// <returns> 受影响行数</returns>
        public int AddOutTab(OutTabDto outTab, string proCode)
        {
            //使用 SqlSugar 事务 添加出库信息并更改生产单状态
            using (var scope = new TransactionScope())
            {
                try
                {
                    var outEntity = _mapper.Map<OutTab>(outTab);
                    var n = _db.Insertable(outEntity).ExecuteCommand();

                    _db.Updateable<Produce>()
                        .SetColumns(it => it.ProStatus == ProStatus.已出库)
                        .Where(it => it.ProCode == proCode)
                        .ExecuteCommand();

                    scope.Complete(); // 提交事务

                    return n;
                }
                catch (Exception ex)
                {
                    // 处理异常
                    // 事务将会自动回滚，因此不需要特殊处理
                    return 0;
                }
            }
        }
        ///// <summary>
        ///// 获取仓库树形图
        ///// </summary>
        ///// <param name="pid">父级ID</param>
        ///// <returns>仓库树形图</returns>
        //public List<WareHouseDto> GetWarehousesList(int pid)
        //{
        //    var query = _db.Queryable<Warehouse>().Where(a => a.Pid == pid).ToList()
        //       .Select(a => new WareHouseDto
        //       {
        //           label = a.WarehouseName,
        //           value = a.WarehouseId.ToString(),
        //           children = GetWarehousesList(a.WarehouseId)
        //       }).ToList();

        //    return query.Count == 0 ? null : query;
        //}
        /// <summary>
        /// 获取仓库树形图
        /// </summary>
        /// <param name="pid">父级ID</param>
        /// <returns>仓库树形图</returns>
        public List<WareHouseDto> GetWarehousesList(int pid)
        {
            string redisKey = "WarehousesList";

            // 尝试从 Redis 中获取数据
            string serializedList = _redis.Get(redisKey);
            List<WareHouseDto> list = null;

            if (!string.IsNullOrEmpty(serializedList))
            {
                // 如果 Redis 中存在数据，直接反序列化返回
                list = JsonConvert.DeserializeObject<List<WareHouseDto>>(serializedList);
            }
            else
            {
                // 如果 Redis 中不存在数据，从数据库中查询
                list = _db.Queryable<Warehouse>().Where(a => a.Pid == pid).ToList()
               .Select(a => new WareHouseDto
               {
                   label = a.WarehouseName,
                   value = a.WarehouseId.ToString(),
                   children = GetWarehousesList(a.WarehouseId)
               }).ToList();

                // 序列化成 JSON 字符串，存入 Redis
                string json = JsonConvert.SerializeObject(list);
                _redis.Set(redisKey, json);
            }

            return list.Count == 0 ? null : list;
        }
        /// <summary>
        /// 编辑出库信息
        /// </summary>
        /// <param name="outId">出库表主键</param>
        /// <returns>返回出库实体</returns>
        public OutTab GetOutTabById(int outId)
        {
            // 根据主键查询实体信息
            var outTab = _db.Queryable<OutTab>().InSingle(outId);
            return outTab;
        }
        /// <summary>
        /// 修改出库信息
        /// </summary>
        /// <param name="outTab">要添加的 出库信息对象</param>
        /// <returns> 受影响行数</returns>
        public int UpdOutInfoById(OutTab outTab)
        {
            return _db.Updateable(outTab).ExecuteCommand();
        }
        /// <summary>
        /// 删除出库信息
        /// </summary>
        /// <param name="outId">出库主键</param>
        /// <returns>受影响行数</returns>
        public int DelOutById(int outId)
        {
            int n = _db.Deleteable<OutTab>().In(outId).ExecuteCommand();
            return n;
        }
        /// <summary>
        /// 导出出库信息
        /// </summary>
        /// <returns> 显示、分页、查询出库列表</returns>
        public List<OutWareHouseDto> GetOutWareExport()
        {

            var query = _db.Queryable<OutTab, Material>((ot, m) => ot.OutId == m.MatId)
                          .Select((ot, m) => new OutWareHouseDto
                          {
                              OutId = ot.OutId,
                              OutType = ot.OutType,
                              OutNum = ot.OutNum,
                              OutTopic = ot.OutTopic,
                              OutDate = ot.OutDate,
                              OutWareHouse = ot.OutWareHouse,
                              Applicant = ot.Applicant,
                              OutName = ot.OutName,
                              Remark = ot.Remark,
                              OutCount = ot.OutCount,
                              //MatId = m.MatId,
                              //MatCode = m.MatCode,
                              //MatName = m.MatName,
                              //MatModel = m.MatModel,
                              //MatBrand = m.MatBrand,
                              //MatUnit = m.MatUnit,
                              //MatType = m.MatType,
                              //MatPerMess = m.MatPerMess,
                              //MatPrice = m.MatPrice,
                              //MatMin = m.MatMin,
                              //MatMax = m.MatMax,
                              //MatDate = m.MatDate,
                              //MatPolice = m.MatPolice,
                              //MatState = m.MatState,
                              //MatDesc = m.MatDesc,
                              //MatImage = m.MatImage,
                          });
            return query.ToList();
        }
        /// <summary>
        /// 生产的显示分页查询
        /// </summary>
        /// <param name="ProCode">生产单号</param>
        /// <param name="pageIndex">当前是第几页</param>
        /// <param name="pageSize">每页需要显示多少条数据</param>
        /// <returns>生产的查询显示分页</returns>
        public PageApiResut<Produce> GetProduceShow(string? ProCode, int pageIndex, int pageSize)
        {
            var ProduceList = _db.Queryable<Produce>()
                .WhereIF(!string.IsNullOrEmpty(ProCode), x => x.ProCode.Contains(ProCode))
                .Where(x => x.ProStatus == ProStatus.已入库);
            ;
            var totalCount = ProduceList.Count();
            var pageList = ProduceList.ToPageList(pageIndex, pageSize).ToList();
            var list = new PageApiResut<Produce>()
            {
                TotalCount = totalCount,
                Data = pageList
            };
            return list;
        }
    }
}
